﻿using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public class StateMachine
{
	public delegate void Callback();
	public enum StateEvent
	{
		ENTER,
		UPDATE,
		EXIT,
	}

	public class StateItem
	{
		public Callback Enter = null;
		public Callback Update = null;
		public Callback Exit = null;
	}

	private StateItem current;
	private StateItem next;
	private Dictionary<object, StateItem> states = new Dictionary<object, StateItem>();

	public void AddState(object _ID)
	{
		if (!states.ContainsKey(_ID))
		{
			states.Add(_ID, new StateItem());
		}

		if (current == null)
		{
			current = states[_ID];
		}
	}

	public void AddCallback(object _ID, StateMachine.StateEvent _event, Callback _callback)
	{
		StateItem item = states[_ID];
		
		switch (_event)
		{
		case StateMachine.StateEvent.ENTER:
			item.Enter = _callback;
			break;
			
		case StateMachine.StateEvent.UPDATE:
			item.Update = _callback;
			break;
			
		case StateMachine.StateEvent.EXIT:
			item.Exit = _callback;
			break;
		}
	}

	public void SetState(object _ID)
	{
		next = states[_ID];
		if (next == null)
		{
			Debug.LogError("ID is not in list of states : " + _ID);
			return;
		}
	}

	// Update must be called by the monobehaviour that created it
	public void Update()
	{
		if (next != null)
		{
			if (current.Exit != null)
			{
				current.Exit();
			}

			current = next;
			next = null;

			if (current.Enter != null)
			{
				current.Enter();
			}
		}

		if (current != null && current.Update != null)
		{
			current.Update();
		}
	}
}
